var Poker = require('../Poker/Poker');
var Const = require('./const');


module.exports = {

   
     //同花顺
    straightFlush: function (cards) {
        if (this.straight(cards) && this.flush(cards)) {
            return {
                'big': this.straight(cards)
            }
        } else {
            return false;
        }
    },
    compareStraightFlush: function (cards1, cards2) {
        return this.compareStraight(cards1, cards2)
    },
    //顺子
    straight: function (cards) {
        var list = [];

        var hasA = false;
        var second = [1, 2, 3, 4, 5];
        var top = [1, 10, 11, 12, 13];
        //判断A做1时的特殊情况
        var len = 0;
        ExObject.eachKeyNum(cards, function (k, v) {
            if (v > 0) {
                if (Poker.getPoint(k) == Poker.Point.A) {
                    hasA = true;
                }
                list.push(Poker.getPoint(k));
            }
            len += v;
        });
        if (len != list.length || len < 2) {
            return false;
        } else {
            list.sort(function (a, b) {
                return a > b;
            });
            if (hasA) {
                var flag1 = true;
                var flag2 = true;
                for (var i = 0; i < len; ++i) {
                    if (list[i] != top[i]) {
                        flag1 = false;
                    }
                    if (list[i] != second[i]) {
                        flag2 = false;
                    }
                }
                if (flag1) {
                    var result = null;
                    ExObject.eachKeyNum(cards, function (k, v) {
                        if (v > 0) {
                            if (Poker.getPoint(k) == Poker.Point.A) {
                                result = { "top": k };
                            }
                        }
                    });
                    return result;
                } else if (flag2) {
                    var result = null;
                    ExObject.eachKeyNum(cards, function (k, v) {
                        if (v > 0) {
                            if (Poker.getPoint(k) == 5) {
                                result = { "big": k };
                            }
                        }
                    });
                    return result;
                }
                return false;
            }
            //没有A
            for (var i = 0; i < len - 1; ++i) {
                if (list[i + 1] - list[i] != 1) {
                    return false;
                }
            }
            var result = null;
            ExObject.eachKeyNum(cards, function (k, v) {
                if (v > 0) {
                    if (Poker.getPoint(k) == list[len - 1]) {
                        result = {
                            "big": k
                        }
                    }
                }
            });
            return result;
        }
    },
    //顺子比较
    compareStraight: function (cards1, cards2) {
        cards1 = this.arrayToObj(cards1);
        cards2 = this.arrayToObj(cards2);
        var a = this.straight(cards1);
        var b = this.straight(cards2);
        if (a['top'] && b['top']) {
            return 0;
        } else if (a['top']) {
            return 1;
        } else if (b['top']) {
            return -1;
        } else if (Poker.getPoint(a['big']) == 1 && Poker.getPoint(b['big']) == 1) {
            return 0;
        } else if (Poker.getPoint(a['big']) == 1) {
            return 1;
        } else if (Poker.getPoint(b['big']) == 1) {
            return -1;
        } else if (Poker.getPoint(a['big']) > Poker.getPoint(b['big'])) {
            return 1;
        } else if (Poker.getPoint(a['big']) < Poker.getPoint(b['big'])) {
            return -1;
        } else {
            return 0;
        }

    },
    //同花
    flush: function (cards) {
        var same = 0;
        var flag = true;
        ExObject.eachKeyNum(cards, function (k, v) {
            if (same == 0) {
                same = Poker.getColor(k);
            } else if (same != Poker.getColor(k)) {
                flag = false;
            }

        });
        if (flag) {
            var list = [];

            ExObject.eachKeyNum(cards, function (k, v) {
                if (v > 0) {
                    list.push(k);
                }
            });
            list.sort(function (a, b) {
                var p1 = Poker.getPoint(a);
                var p2 = Poker.getPoint(b);
                var rule = Const.CompScore;
                return rule[p1] > rule[p2];
            });

            if (flag == true && list.length > 0) {
                return { "big": list }
            }
        } else {
            return false;
        }
    },
    //同花比较 a > b  -1 0 1
    compareFlush: function (cards1, cards2) {
        cards1 = this.arrayToObj(cards1);
        cards2 = this.arrayToObj(cards2);
        var a = this.flush(cards1);
        var b = this.flush(cards2);
        var list1 = a.big;
        var list2 = b.big;

        var len = list1.length;
        for (var i = len - 1; i >= 0; --i) {
            if (this.compCard(list1[i], list2[i]) == 0) {
                continue;
            }
            return this.compCard(list1[i], list2[i]);
        }
        return 0;
    },

    //炸弹
    fourKind: function (cards) {
        var num4 = 0;
        var num1 = 0;
        var len = 0
        var cardNum = {};
        ExObject.eachKeyNum(cards, function (k, v) {
            len += v;
            var key = Poker.getPoint(k);
            if (v > 0) {
                if (!cardNum[key]) {
                    cardNum[key] = 1;
                } else {
                    cardNum[key] += 1;
                }
            }
        });

        if (len != 5) {
            return false;
        } else {
            ExObject.eachKeyNum(cardNum, function (k, v) {
                if (v == 4) {
                    num4 = k;
                }
                if (v == 1) {
                    num1 = k;
                }
            });
            if (num4 && num1) {
                var result = null;
                ExObject.eachKeyNum(cards, function (k, v) {
                    var key = Poker.getPoint(k);
                    if (key == num4) {
                        result = {
                            "big": k
                        }
                    }
                });
                return result;
            } else {
                return false;
            }
        }
    },
    //比较炸弹
    compareFourKind: function (cards1, cards2) {
        cards1 = this.arrayToObj(cards1);
        cards2 = this.arrayToObj(cards2);
        var a = this.fourKind(cards1);
        var b = this.fourKind(cards2);
        var card1 = a['big'];
        var card2 = b['big'];

        return this.compCard(card1, card2);
    },
    //三带二 葫芦
    fullHouse: function (cards) {
        var num3 = 0;
        var num2 = 0;
        var len = 0;
        var cardNum = {};
        ExObject.eachKeyNum(cards, function (k, v) {
            len += v;
            var key = Poker.getPoint(k);
            if (v > 0) {
                if (!cardNum[key]) {
                    cardNum[key] = 1;
                } else {
                    cardNum[key] += 1;
                }
            }
        });

        ExObject.eachKeyNum(cardNum, function (k, v) {
            if (v == 3) {
                num3 = k;
            }
            if (v == 2) {
                num2 = k;
            }
        });

        if (len != 5) {
            return false;
        } else {
            if (num3 && num2) {
                var result = null;
                ExObject.eachKeyNum(cardNum, function (k, v) {
                    var key = Poker.getPoint(k);
                    if (key == num3) {
                        result = {
                            "big": k
                        }
                    }
                });
                return result;
            } else {
                return false
            }
        }
    },
    //比较三带二
    compareFullHouse: function (cards1, cards2) {
        cards1 = this.arrayToObj(cards1);
        cards2 = this.arrayToObj(cards2);
        var a = this.fullHouse(cards1);
        var b = this.fullHouse(cards2);
        var card1 = a['big'];
        var card2 = b['big'];

        return this.compCard(card1, card2);

    },
    //三不带
    threeKind: function (cards) {
        var num3 = 0;
        var cardNum = {};
        var len = 0;
        ExObject.eachKeyNum(cards, function (k, v) {
            len += v;
            var key = Poker.getPoint(k);
            if (v > 0) {
                if (!cardNum[key]) {
                    cardNum[key] = 1;
                } else {
                    cardNum[key] += 1;
                }
            }
        });
        ExObject.eachKeyNum(cardNum, function (k, v) {

            if (v == 3) {
                num3 = k;
            }
        });
        if (len == 5 || len == 3) {
            if (num3) {
                var result = null;
                ExObject.eachKeyNum(cardNum, function (k, v) {
                    var key = Poker.getPoint(k);
                    if (key == num3) {
                        result = {
                            "big": k
                        }
                    }
                });
                return result;
            } else {
                return false;
            }
        } else {
            return false;
        }
    },
    compareThreeKind: function (cards1, cards2) {
        cards1 = this.arrayToObj(cards1);
        cards2 = this.arrayToObj(cards2);
        var a = this.threeKind(cards1);
        var b = this.threeKind(cards2);
        var card1 = a['big'];
        var card2 = b['big'];

        return this.compCard(card1, card2);
    },
    //两对
    twoPair: function (cards) {
        var num21 = 0;
        var num22 = 0;
        var len = 0;
        var cardNum = {};

        ExObject.eachKeyNum(cards, function (k, v) {
            len += v;
            var key = Poker.getPoint(k);
            if (v > 0) {
                if (!cardNum[key]) {
                    cardNum[key] = 1;
                } else {
                    cardNum[key] += 1;
                }
            }
        });

        ExObject.eachKeyNum(cardNum, function (k, v) {
            if (v == 2 && num21 == 0) {
                num21 = k;
            } else if (v == 2 && num22 == 0) {
                num22 = k;
            }
        });

        if (len == 5 && num21 && num22) {
            if (this.compCard(num21, num22) < 0) {
                var temp = num21;
                num21 = num22;
                num22 = temp;
            }
            ExObject.eachKeyNum(cards, function (k, v) {
                if (num21 == Poker.getPoint(k)) {
                    num21 = k;
                }
                if (num22 == Poker.getPoint(k)) {
                    num22 = k;
                }
            });
            return {
                "big": num21,
                "other": num22
            }

        } else {
            return false;
        }
    },
    compareTwoPair: function (cards1, cards2) {
        cards1 = this.arrayToObj(cards1);
        cards2 = this.arrayToObj(cards2);
        var a = this.twoPair(cards1);
        var b = this.twoPair(cards2);
        var card1 = a['big'];
        var card12 = a['other'];
        var card2 = b['big'];
        var card22 = b['other'];

        if (this.compCard(card1, card2) == 0 && this.compCard(card12, card22) == 0) {
            return 0;
        } else if (this.compCard(card1, card2) == 1) {
            return 1;
        } else if (this.compCard(card1, card2) == 0) {
            if (this.compCard(card12, card22) == 1) {
                return 1;
            } else {
                return -1;
            }
        } else {
            return -1;
        }
    },
    //一对
    onePair: function (cards) {
        var num2 = 0;
        var cardNum = {};
        var len = 0;
        var list = [];
        ExObject.eachKeyNum(cards, function (k, v) {
            len += v;
            var key = Poker.getPoint(k);
            if (v > 0) {
                if (!cardNum[key]) {
                    cardNum[key] = 1;
                } else {
                    cardNum[key] += 1;
                }
            }
        });
        ExObject.eachKeyNum(cardNum, function (k, v) {
            if (v == 2) {
                num2 = k;
            }
        });
        ExObject.eachKeyNum(cards, function (k, v) {
            if (num2 == Poker.getPoint(k)) {
                num2 = k;
            }else{
                list.push(k)
            }
        });

        if (len == 5 || len == 3) {
            if (num2) {
                return {
                    "big": num2,
                    "other":list
                }
            } else {
                return false;
            }
        } else {
            return false;
        }
    },
    compareOnePair: function (card1, card2) {
        card1 = this.arrayToObj(card1);
        card2 = this.arrayToObj(card2);
        var a = this.onePair(card1);
        var b = this.onePair(card2);
        if(this.compCard(a['big'],b['big']) == 0){
            return this.compareNormal(a['other'],b['other'])
        }else{
            return this.compCard(a['big'], b['big']);    
        }
    },
    //散牌
    normalCards: function (cards) {
        var list = [];
        ExObject.eachKeyNum(cards, function (k, v) {
            if (v > 0)
                list.push(k);
        });
        list.sort(function (a, b) {
            var p1 = Poker.getPoint(a);
            var p2 = Poker.getPoint(b);
            var rule = Const.CompScore;
            return rule[p1] > rule[p2];
        });
        return {
            "big": list
        }
    },
    compareNormal: function (card1, card2) {
        card1 = this.arrayToObj(card1);
        card2 = this.arrayToObj(card2);
        var a = this.normalCards(card1);
        var b = this.normalCards(card2);
        var list1 = a.big;
        var list2 = b.big;

        if (list1.length > list2.length) {
            var len = list2.length;
            list1 = list1.slice(2);
            for (var i = len - 1; i >= 0; --i) {
                if (this.compCard(list1[i], list2[i]) == 0) {
                    continue;
                }
                return this.compCard(list1[i], list2[i]);
            }
            return 1;
        } else if (list1.length < list2.length) {
            var len = list1.length;
            list2 = list2.slice(2);
            for (var i = len - 1; i >= 0; --i) {
                if (this.compCard(list1[i], list2[i]) == 0) {
                    continue;
                }
                return this.compCard(list1[i], list2[i]);
            }
            return -1;
        }

        var len = list1.length;
        for (var i = len - 1; i >= 0; --i) {
            if (this.compCard(list1[i], list2[i]) == 0) {
                continue;
            }
            return this.compCard(list1[i], list2[i]);
        }
        return 0;
    },
    //比较牌
    compCard: function (card1, card2) {
        var p1 = Poker.getPoint(card1);
        var p2 = Poker.getPoint(card2);

        //var c1 = Poker.getColor(card1);
        //var c2 = Poker.getColor(card2);

        var rule = Const.CompScore;
        // var ruleColor = Const.CompColor;
        if (rule[p1] == rule[p2]) {
            return 0;
        }
        return rule[p1] > rule[p2] ? 1 : -1;
    },

    sumPattern: function (cardsArrayorObj) {
        var cards={};
        if (!ExObject.isArray(cardsArrayorObj)) {
            cards = cardsArrayorObj;
        } else {
            cardsArrayorObj.forEach(function (v) {
                cards[v] = 1;
            });
        }
        //console.log('sumPattern')
        //console.log(cardsArrayorObj);


        if (this.straight(cards) && this.flush(cards)) {
            return {
                'pattern': Const.Pattern.BIGBRO,
                'compare': this.straight(cards)
            }
        } else if (this.fourKind(cards)) {
            return {
                'pattern': Const.Pattern.BOOM,
                'compare': this.fourKind(cards)
            }
        } else if (this.fullHouse(cards)) {
            return {
                'pattern': Const.Pattern.FULLHOUSE,
                'compare': this.fullHouse(cards)
            }
        } else if (this.flush(cards)) {
            return {
                'pattern': Const.Pattern.FLUSH,
                'compare': this.flush(cards)
            }
        } else if (this.straight(cards)) {
            return {
                'pattern': Const.Pattern.STRAIGHT,
                'compare': this.straight(cards)
            }
        } else if (this.threeKind(cards)) {
            return {
                'pattern': Const.Pattern.THREEKIND,
                'compare': this.threeKind(cards)
            }
        } else if (this.twoPair(cards)) {
            return {
                'pattern': Const.Pattern.PAIR2,
                'compare': this.twoPair(cards)
            }
        } else if (this.onePair(cards)) {
            return {
                'pattern': Const.Pattern.PAIR,
                'compare': this.onePair(cards)
            }
        } else {
            return {
                'pattern': Const.Pattern.NONE,
                'compare': this.normalCards(cards)
            }
        }
    },

    checkHead: function (cardsArray) {
        var cards = {};
        cardsArray.forEach(function (v) {
            cards[v] = 1;
        })
        if (this.threeKind(cards)) {
            return Const.Pattern.THREEKIND;
        } else if (this.onePair(cards)) {
            return Const.Pattern.PAIR;
        } else {
            return Const.Pattern.NONE;
        }
    },
    getCompare: function (pattern) {

        if (pattern == Const.Pattern.BIGBRO) {
            return this.compareStraightFlush.bind(this);
        } else if (pattern == Const.Pattern.BOOM) {
            return this.compareFourKind.bind(this);
        }
        else if (pattern == Const.Pattern.FULLHOUSE) {
            return this.compareFullHouse.bind(this);
        }
        else if (pattern == Const.Pattern.FLUSH) {
            return this.compareFlush.bind(this);
        }
        else if (pattern == Const.Pattern.STRAIGHT) {
            return this.compareStraight.bind(this);
        }
        else if (pattern == Const.Pattern.THREEKIND) {
            return this.compareThreeKind.bind(this);
        }
        else if (pattern == Const.Pattern.PAIR2) {
            return this.compareTwoPair.bind(this);
        }
        else if (pattern == Const.Pattern.PAIR) {
            return this.compareOnePair.bind(this);
        } else {
            return this.compareNormal.bind(this);
        }
    },
    isStandard: function (sumCards) {
        var head = sumCards['head'];
        var body = sumCards['body'];
        var foot = sumCards['footer'];

        var headPattern = this.checkHead(head);
        var bodyPattern = this.sumPattern(body)['pattern'];
        var footPattern = this.sumPattern(foot)['pattern'];


        if (footPattern > bodyPattern && bodyPattern > headPattern) {
            return true;
        }
        if (footPattern == bodyPattern && bodyPattern > headPattern) {
            var comp = this.getCompare(footPattern);
            if (comp(foot, body) < 0 ) {
                return false;
            }
            return true;
        }
        if (bodyPattern == headPattern && footPattern > bodyPattern) {
            var comp = this.getCompare(bodyPattern);
            if (comp(body, head) < 1) {
                return false;
            }
            return true;
        }
        if (bodyPattern == headPattern && footPattern == bodyPattern) {
            var comp = this.getCompare(bodyPattern);
            if (comp(body, head) < 1 || comp(foot, body) < 0) {
                return false;
            }
            return true;
        }
        if (bodyPattern < headPattern || footPattern < bodyPattern) {
            return false;
        }
        return true;
    },
    isStandardComp: function (cards) {
        var head = cards['head']['cards'];
        var body = cards['body']['cards'];
        var foot = cards['foot']['cards'];

        var headPattern = cards['head']['pattern'];
        var bodyPattern = cards['body']['pattern'];
        var footPattern = cards['foot']['pattern'];


        if (footPattern > bodyPattern && bodyPattern > headPattern) {
            return true;
        }
        if (footPattern == bodyPattern && bodyPattern > headPattern) {
            var comp = this.getCompare(footPattern);
            if (comp(foot, body) < 0) {
                return false;
            }
            return true;
        }
        if (bodyPattern == headPattern && footPattern > bodyPattern) {
            var comp = this.getCompare(bodyPattern);
            if (comp(body, head) < 1) {
                return false;
            }
            return true;
        }
        if (bodyPattern == headPattern && footPattern == bodyPattern) {
            var comp = this.getCompare(bodyPattern);
            if (comp(body, head) < 1 || comp(foot, body) < 0) {
                return false;
            }
            return true;
        }
        if (bodyPattern < headPattern || footPattern < bodyPattern) {
            return false;
        }
        return true;
    },
    compareAll: function (sum1, sum2,long) {
        var patternHead1 = sum1['head']['pattern']
        var patternHead2 = sum2['head']['pattern']
        var headScore = 1;
        var cardsHead1 = sum1['head']['cards']
        var cardsHead2 = sum2['head']['cards']

        var patternBody1 = sum1['body']['pattern']
        var patternBody2 = sum2['body']['pattern']
        var bodyScore = 2;
        var cardsBody1 = sum1['body']['cards']
        var cardsBody2 = sum2['body']['cards']

        var patternFoot1 = sum1['foot']['pattern']
        var patternFoot2 = sum2['foot']['pattern']
        var footScore = 3;
        var cardsFoot1 = sum1['foot']['cards']
        var cardsFoot2 = sum2['foot']['cards']

        var count = {}
        if (patternHead1 == Const.Pattern.THREEKIND || patternHead2 == Const.Pattern.THREEKIND) {
            headScore = 3+long;
        }
        if (patternBody1 == Const.Pattern.BOOM || patternBody2 == Const.Pattern.BOOM) {
            bodyScore = 7+long;
        }
        if (patternFoot1 == Const.Pattern.BOOM || patternFoot2 == Const.Pattern.BOOM) {
            footScore = 7+long;
        }
        if (patternBody1 == Const.Pattern.BIGBRO || patternBody2 == Const.Pattern.BIGBRO) {
            bodyScore = 8+long;
        }
        if (patternFoot1 == Const.Pattern.BIGBRO || patternFoot2 == Const.Pattern.BIGBRO) {
            footScore = 8+long;
        }

        if (patternHead1 > patternHead2) {
            count['head'] = headScore;
        } else if (patternHead1 == patternHead2) {
            var comp = this.getCompare(patternHead1);
            if (comp(cardsHead1, cardsHead2) == 1) {
                count['head'] = headScore;
            } else if (comp(cardsHead1, cardsHead2) == -1) {
                count['head'] = -headScore;
            } else {
                count['head'] = 0;
            }
        } else {
            count['head'] = -headScore;
        }

        if (patternBody1 > patternBody2) {
            count['body'] = bodyScore;
        } else if (patternBody1 == patternBody2) {
            var comp = this.getCompare(patternBody1);
            if (comp(cardsBody1, cardsBody2) == 1) {
                count['body'] = bodyScore;
            } else if (comp(cardsBody1, cardsBody2) == -1) {
                count['body'] = -bodyScore;
            } else {
                count['body'] = 0;
            }
        } else {
            count['body'] = -bodyScore;
        }

        if (patternFoot1 > patternFoot2) {
            count['foot'] = footScore;
        } else if (patternFoot1 == patternFoot2) {
            var comp = this.getCompare(patternFoot1);
            if (comp(cardsFoot1, cardsFoot2) == 1) {
                count['foot'] = footScore;
            } else if (comp(cardsFoot1, cardsFoot2) == -1) {
                count['foot'] = -footScore;
            } else {
                count['foot'] = 0;
            }
        } else {
            count['foot'] = -footScore;
        }

        if(count['head'] == 0){
            if(count['foot'] > 0){
                count['head'] = headScore;
            }else if(count['foot'] < 0){
                count['head'] = -headScore;
            }
        }
        if(count['foot'] == 0 && count['body'] == 0){
            if(count['head'] > 0){
                count['body'] = bodyScore;
                count['foot'] = footScore;
            }else if(count['head'] < 0){
                count['body'] = -bodyScore;
                count['foot'] = -footScore
            }
        }

        if(count['body'] == 0){
            if(count['foot'] > 0) {
                count['body'] = bodyScore;
            }else if(count['foot'] < 0){
                count['body'] = -bodyScore;
            }
        }
        if(count['foot'] == 0){
            if(count['body'] > 0){
                count['foot'] = footScore;
            }else if(count['body'] < 0){
                count['foot'] = -footScore;
            }
        }

        return count;
    },
    loseAll: function (sum,long) {
        var patternHead = sum['head']['pattern']
        var headScore = 1;
        var patternBody = sum['body']['pattern']
        var bodyScore = 2;
        var patternFoot = sum['foot']['pattern']
        var footScore = 3;

        if (patternHead == Const.Pattern.THREEKIND) {
            headScore = 3+long;
        }
        if (patternBody == Const.Pattern.BOOM) {
            bodyScore = 7+long;
        }
        if (patternFoot == Const.Pattern.BOOM) {
            footScore = 7+long;
        }
        if (patternBody == Const.Pattern.BIGBRO) {
            bodyScore = 8+long;
        }
        if (patternFoot == Const.Pattern.BIGBRO) {
            footScore = 8+long;
        }

        return {
            'head': headScore,
            'body': bodyScore,
            'foot': footScore
        }

    },
    fomatCards: function (cards) {
        var cardsFoot
        if (cards['footer']) {
            cardsFoot = cards['footer'];
        } else {
            cardsFoot = cards['foot'];
        }
        return {
            'head': {
                'pattern': this.checkHead(cards['head']),
                'cards': cards['head'].slice()
            },
            'body': {
                'pattern': this.sumPattern(cards['body'])['pattern'],
                'cards': cards['body'].slice()
            },
            'foot': {
                'pattern': this.sumPattern(cardsFoot)['pattern'],
                'cards': cardsFoot.slice()
            },
        }
    },
    isGun: function (count) {
        if (count['head'] > 0 && count['body'] > 0 && count['foot'] > 0) {
            return true;
        }
        if (count['head'] < 0 && count['body'] < 0 && count['foot'] < 0) {
            return true;
        }
        return false;
    },
    arrayToObj: function (cardArrayObj) {
        var cards = {}
        if (!ExObject.isArray(cardArrayObj)) {
            cards = cardArrayObj;
        } else {

            cardArrayObj.forEach(function (v) {
                cards[v] = 1;
            });
        }
        return cards;
    },
}